<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>C++面试题 | whoway</title>
    <meta name="description" content="Personal Blog Website">
    <link rel="icon" href="/images/photo.jpg">
  <link rel="manifest" href="/images/photo.jpg">
  <link rel="apple-touch-icon" href="/images/photo.jpg">
  <meta http-quiv="pragma" cotent="no-cache">
  <meta http-quiv="pragma" cotent="no-cache,must-revalidate">
  <meta http-quiv="expires" cotent="0">
    
    <link rel="preload" href="/assets/css/0.styles.0dbae9ec.css" as="style"><link rel="preload" href="/assets/js/app.c70e21ad.js" as="script"><link rel="preload" href="/assets/js/25.14067b60.js" as="script"><link rel="prefetch" href="/assets/js/10.15222a53.js"><link rel="prefetch" href="/assets/js/100.7e0e5a86.js"><link rel="prefetch" href="/assets/js/101.efd59f25.js"><link rel="prefetch" href="/assets/js/102.dfbdc06c.js"><link rel="prefetch" href="/assets/js/103.d3ab2109.js"><link rel="prefetch" href="/assets/js/104.117957ef.js"><link rel="prefetch" href="/assets/js/105.046e8ff3.js"><link rel="prefetch" href="/assets/js/106.aebdc17d.js"><link rel="prefetch" href="/assets/js/107.248733c2.js"><link rel="prefetch" href="/assets/js/108.a2fecadc.js"><link rel="prefetch" href="/assets/js/109.35196857.js"><link rel="prefetch" href="/assets/js/11.770642f2.js"><link rel="prefetch" href="/assets/js/110.cf3d973c.js"><link rel="prefetch" href="/assets/js/111.f985889a.js"><link rel="prefetch" href="/assets/js/112.ad614f41.js"><link rel="prefetch" href="/assets/js/113.f666653c.js"><link rel="prefetch" href="/assets/js/114.c6c3f384.js"><link rel="prefetch" href="/assets/js/115.e51d3c2f.js"><link rel="prefetch" href="/assets/js/116.4f4b39f5.js"><link rel="prefetch" href="/assets/js/117.99352e11.js"><link rel="prefetch" href="/assets/js/118.c6ae6572.js"><link rel="prefetch" href="/assets/js/119.4ccbe778.js"><link rel="prefetch" href="/assets/js/12.042a92ff.js"><link rel="prefetch" href="/assets/js/120.edda1c4f.js"><link rel="prefetch" href="/assets/js/121.30a638ed.js"><link rel="prefetch" href="/assets/js/122.6efcefb1.js"><link rel="prefetch" href="/assets/js/123.91e6665b.js"><link rel="prefetch" href="/assets/js/124.f27e3d7e.js"><link rel="prefetch" href="/assets/js/125.c75712d5.js"><link rel="prefetch" href="/assets/js/126.ed756cce.js"><link rel="prefetch" href="/assets/js/127.2f06c74c.js"><link rel="prefetch" href="/assets/js/128.d5f6f30e.js"><link rel="prefetch" href="/assets/js/129.508b7eed.js"><link rel="prefetch" href="/assets/js/13.b5280c37.js"><link rel="prefetch" href="/assets/js/130.dc05f9aa.js"><link rel="prefetch" href="/assets/js/131.e0ba69b1.js"><link rel="prefetch" href="/assets/js/132.d79bcaa4.js"><link rel="prefetch" href="/assets/js/133.34acc01a.js"><link rel="prefetch" href="/assets/js/134.dabf64d5.js"><link rel="prefetch" href="/assets/js/135.ad90c915.js"><link rel="prefetch" href="/assets/js/136.dbb0074f.js"><link rel="prefetch" href="/assets/js/137.284ad365.js"><link rel="prefetch" href="/assets/js/138.a4b6856f.js"><link rel="prefetch" href="/assets/js/139.c9c1e20f.js"><link rel="prefetch" href="/assets/js/14.df02ba38.js"><link rel="prefetch" href="/assets/js/140.8b0a9269.js"><link rel="prefetch" href="/assets/js/141.9c7759c5.js"><link rel="prefetch" href="/assets/js/142.a4201a82.js"><link rel="prefetch" href="/assets/js/143.d7da6e8c.js"><link rel="prefetch" href="/assets/js/144.5e48e65d.js"><link rel="prefetch" href="/assets/js/145.a0e2633c.js"><link rel="prefetch" href="/assets/js/146.3c775f9b.js"><link rel="prefetch" href="/assets/js/147.22add89a.js"><link rel="prefetch" href="/assets/js/148.cfde1009.js"><link rel="prefetch" href="/assets/js/149.ffc835b5.js"><link rel="prefetch" href="/assets/js/15.fbdfc4ee.js"><link rel="prefetch" href="/assets/js/150.406c4b20.js"><link rel="prefetch" href="/assets/js/151.b2040eea.js"><link rel="prefetch" href="/assets/js/152.7bc65661.js"><link rel="prefetch" href="/assets/js/153.1d7c65e3.js"><link rel="prefetch" href="/assets/js/154.1309de49.js"><link rel="prefetch" href="/assets/js/155.81d3ee1f.js"><link rel="prefetch" href="/assets/js/156.154a4ef2.js"><link rel="prefetch" href="/assets/js/16.e5eb6147.js"><link rel="prefetch" href="/assets/js/17.57853c4a.js"><link rel="prefetch" href="/assets/js/18.cb9d7518.js"><link rel="prefetch" href="/assets/js/19.f354dc47.js"><link rel="prefetch" href="/assets/js/2.570d8a23.js"><link rel="prefetch" href="/assets/js/20.b5af7fad.js"><link rel="prefetch" href="/assets/js/21.0b1928fe.js"><link rel="prefetch" href="/assets/js/22.f78666de.js"><link rel="prefetch" href="/assets/js/23.29c3f366.js"><link rel="prefetch" href="/assets/js/24.6f596516.js"><link rel="prefetch" href="/assets/js/26.74ba4989.js"><link rel="prefetch" href="/assets/js/27.13d60edd.js"><link rel="prefetch" href="/assets/js/28.9523cb32.js"><link rel="prefetch" href="/assets/js/29.8ec842e9.js"><link rel="prefetch" href="/assets/js/3.3fb3d2e0.js"><link rel="prefetch" href="/assets/js/30.805597a8.js"><link rel="prefetch" href="/assets/js/31.831b195d.js"><link rel="prefetch" href="/assets/js/32.063c672d.js"><link rel="prefetch" href="/assets/js/33.6d93fac3.js"><link rel="prefetch" href="/assets/js/34.56e8263c.js"><link rel="prefetch" href="/assets/js/35.dbe688bb.js"><link rel="prefetch" href="/assets/js/36.dc5af2c1.js"><link rel="prefetch" href="/assets/js/37.0a7494f6.js"><link rel="prefetch" href="/assets/js/38.fe4fc171.js"><link rel="prefetch" href="/assets/js/39.f5ed5e92.js"><link rel="prefetch" href="/assets/js/4.2c405ec8.js"><link rel="prefetch" href="/assets/js/40.fe7e2714.js"><link rel="prefetch" href="/assets/js/41.30b0811d.js"><link rel="prefetch" href="/assets/js/42.76f52d62.js"><link rel="prefetch" href="/assets/js/43.e7bb0817.js"><link rel="prefetch" href="/assets/js/44.ead0e883.js"><link rel="prefetch" href="/assets/js/45.235df046.js"><link rel="prefetch" href="/assets/js/46.5f09e829.js"><link rel="prefetch" href="/assets/js/47.67116354.js"><link rel="prefetch" href="/assets/js/48.31f34543.js"><link rel="prefetch" href="/assets/js/49.10b5ebba.js"><link rel="prefetch" href="/assets/js/5.6f47322c.js"><link rel="prefetch" href="/assets/js/50.c0f0b7f1.js"><link rel="prefetch" href="/assets/js/51.5143f3bf.js"><link rel="prefetch" href="/assets/js/52.eeddfd48.js"><link rel="prefetch" href="/assets/js/53.eb790db5.js"><link rel="prefetch" href="/assets/js/54.8fe5421c.js"><link rel="prefetch" href="/assets/js/55.d8f9004b.js"><link rel="prefetch" href="/assets/js/56.62ac9b92.js"><link rel="prefetch" href="/assets/js/57.a9caec0d.js"><link rel="prefetch" href="/assets/js/58.f93fc522.js"><link rel="prefetch" href="/assets/js/59.a81a03aa.js"><link rel="prefetch" href="/assets/js/6.8c2ea393.js"><link rel="prefetch" href="/assets/js/60.ab782775.js"><link rel="prefetch" href="/assets/js/61.6dd12daf.js"><link rel="prefetch" href="/assets/js/62.76f4b01f.js"><link rel="prefetch" href="/assets/js/63.6f8a4742.js"><link rel="prefetch" href="/assets/js/64.6f8bb1fa.js"><link rel="prefetch" href="/assets/js/65.4120a44b.js"><link rel="prefetch" href="/assets/js/66.360c2d2b.js"><link rel="prefetch" href="/assets/js/67.26f84d32.js"><link rel="prefetch" href="/assets/js/68.68f45e5e.js"><link rel="prefetch" href="/assets/js/69.e311eb56.js"><link rel="prefetch" href="/assets/js/7.6762b2d7.js"><link rel="prefetch" href="/assets/js/70.cea82674.js"><link rel="prefetch" href="/assets/js/71.783ddcf7.js"><link rel="prefetch" href="/assets/js/72.e5467385.js"><link rel="prefetch" href="/assets/js/73.b8fb681b.js"><link rel="prefetch" href="/assets/js/74.1bae37db.js"><link rel="prefetch" href="/assets/js/75.024387e5.js"><link rel="prefetch" href="/assets/js/76.a8e53010.js"><link rel="prefetch" href="/assets/js/77.8c55500a.js"><link rel="prefetch" href="/assets/js/78.7ce90bf5.js"><link rel="prefetch" href="/assets/js/79.ef71713f.js"><link rel="prefetch" href="/assets/js/8.788a6364.js"><link rel="prefetch" href="/assets/js/80.acad589d.js"><link rel="prefetch" href="/assets/js/81.02670d10.js"><link rel="prefetch" href="/assets/js/82.53b7b1ac.js"><link rel="prefetch" href="/assets/js/83.99eb8581.js"><link rel="prefetch" href="/assets/js/84.d1535ce3.js"><link rel="prefetch" href="/assets/js/85.fe2b7de9.js"><link rel="prefetch" href="/assets/js/86.41850272.js"><link rel="prefetch" href="/assets/js/87.1cdc6df9.js"><link rel="prefetch" href="/assets/js/88.01bf3461.js"><link rel="prefetch" href="/assets/js/89.17c69819.js"><link rel="prefetch" href="/assets/js/9.3813842d.js"><link rel="prefetch" href="/assets/js/90.f6ae7e35.js"><link rel="prefetch" href="/assets/js/91.507bc284.js"><link rel="prefetch" href="/assets/js/92.90551782.js"><link rel="prefetch" href="/assets/js/93.dc442d78.js"><link rel="prefetch" href="/assets/js/94.315f4e94.js"><link rel="prefetch" href="/assets/js/95.ccd6c6bf.js"><link rel="prefetch" href="/assets/js/96.0c6d89d0.js"><link rel="prefetch" href="/assets/js/97.1a9f10a9.js"><link rel="prefetch" href="/assets/js/98.43be3caa.js"><link rel="prefetch" href="/assets/js/99.54c8207b.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0dbae9ec.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">whoway</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link router-link-active">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link router-link-active">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>C++面试题</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#📑-目录" class="sidebar-link">📑 目录</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#✅虚函数" class="sidebar-link">✅虚函数</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_1-虚函数表vtbl" class="sidebar-link">1.虚函数表vtbl</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-构造一个派生类对象的过程：" class="sidebar-link">2.构造一个派生类对象的过程：</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-1-是先构造父类的虚表指针还是先构造父类的成员？" class="sidebar-link">2.1.是先构造父类的虚表指针还是先构造父类的成员？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-2-虚表指针和构造函数体那个先被构造？" class="sidebar-link">2.2.虚表指针和构造函数体那个先被构造？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_3-c-运行构造函数的时候虚函数表被构造出来了么？" class="sidebar-link">3.c++运行构造函数的时候虚函数表被构造出来了么？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_4-析构一个派生类对象的过程：" class="sidebar-link">4.析构一个派生类对象的过程：</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#✅基础" class="sidebar-link">✅基础</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_1-vector是线程安全的吗？" class="sidebar-link">1.vector是线程安全的吗？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-c-是不是类型安全的呢？" class="sidebar-link">2.C++是不是类型安全的呢？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_3-sizeof只有1个虚析构函数的空类呢？" class="sidebar-link">3.sizeof只有1个虚析构函数的空类呢？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_4-构造函数为什么不能是虚函数？" class="sidebar-link">4.构造函数为什么不能是虚函数？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_5-为何空类的大小不是零？" class="sidebar-link">5.为何空类的大小不是零？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_6-我能从构造函数调用虚函数吗？" class="sidebar-link">6.我能从构造函数调用虚函数吗？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_7-内存泄露及解决办法：" class="sidebar-link">7.内存泄露及解决办法：</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_8-怎么检测内存泄漏？" class="sidebar-link">8.怎么检测内存泄漏？</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#✅平常做题错题" class="sidebar-link">✅平常做题错题</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_1-测试" class="sidebar-link">1.测试</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_02-在-c-语言中，对函数参数默认值描述正确的是？" class="sidebar-link">02.在 c++ 语言中，对函数参数默认值描述正确的是？</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#✅c-输入输出io" class="sidebar-link">✅C++输入输出IO</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_01-iostream的设计初衷" class="sidebar-link">01.iostream的设计初衷</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_02-iostream的特点" class="sidebar-link">02.iostream的特点</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#✅c-高阶论题" class="sidebar-link">✅C++高阶论题</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_01-c-惯用法" class="sidebar-link">01.C++惯用法</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_1-1-raii-资源获取即初始化" class="sidebar-link">1.1.RAII(资源获取即初始化)</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_1-2-pimpl" class="sidebar-link">1.2.pImpl</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_1-3-copy-and-swap" class="sidebar-link">1.3.copy and swap</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_02-value-semantics和object-semantics" class="sidebar-link">02.value semantics和object semantics</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-1-值语义（value-semantics）" class="sidebar-link">2.1.值语义（value semantics）</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-2-对象语义（object-semantics）" class="sidebar-link">2.2.对象语义（object semantics）</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_2-3-优点缺点对比" class="sidebar-link">2.3.优点缺点对比</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_03-c-惯用法和value-semantics组合拳" class="sidebar-link">03.C++惯用法和value semantics组合拳</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_3-1-c-的值语义是『双刃剑』" class="sidebar-link">3.1.C++的值语义是『双刃剑』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_3-3-问题：智能指针？" class="sidebar-link">3.3.问题：智能指针？</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_04-c-语言层面高度探讨" class="sidebar-link">04.C++语言层面高度探讨</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_05-c-的编程范式" class="sidebar-link">05.C++的编程范式</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_5-1-过程式编程" class="sidebar-link">5.1.过程式编程</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_5-2-基于对象编程" class="sidebar-link">5.2.基于对象编程</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_5-3-面向对象编程" class="sidebar-link">5.3.面向对象编程</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_5-4-泛型编程" class="sidebar-link">5.4.泛型编程</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#_5-5-函数式编程" class="sidebar-link">5.5.函数式编程</a></li></ul></li><li><a href="/01.Language/Cpp/00.C%2B%2B%E9%9D%A2%E8%AF%95%E9%A2%98.html#🔋-参考资料" class="sidebar-link">🔋 参考资料</a><ul class="sidebar-sub-headers"></ul></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="c-面试题"><a href="#c-面试题" class="header-anchor">#</a> C++面试题</h1> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>&lt;font style=&quot;background:yellow&quot;&gt;
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h2 id="📑-目录"><a href="#📑-目录" class="header-anchor">#</a> 📑 目录</h2> <p>[TOC]</p> <h2 id="✅虚函数"><a href="#✅虚函数" class="header-anchor">#</a> ✅虚函数</h2> <h3 id="_1-虚函数表vtbl"><a href="#_1-虚函数表vtbl" class="header-anchor">#</a> 1.虚函数表<code>vtbl</code></h3> <ol><li><font style="background:yellow;">编译器在<strong>编译时期</strong>为每个带虚函数的类创建一份虚函数表</font></li> <li><strong>实例化</strong>对象时, 编译器自动将类对象的虚表指针指向这个虚函数表</li></ol> <ul><li>参考自：《收割BAT：<a href="https://www.nowcoder.com/tutorial/10018/index" target="_blank" rel="noopener noreferrer">C++校招学习路线总结<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>》，特立独行MVP</li></ul> <h3 id="_2-构造一个派生类对象的过程："><a href="#_2-构造一个派生类对象的过程：" class="header-anchor">#</a> 2.构造一个派生类对象的过程：</h3> <ul><li><p>1.构造<strong>基类</strong>部分：</p> <ul><li>1.将实例的虚表指针指向<strong>基类的vtbl</strong></li> <li>2.构造基类的<strong>成员变量</strong></li> <li>3.<font style="background:yellow;">执行基类的<strong>构造函数函数体</strong></font></li></ul></li> <li><p>2.<strong>递归</strong>构造派生类部分：</p> <ul><li>1.将实例的虚表指针指向<strong>派生类vtbl</strong></li> <li>2.构造派生类的成员变量</li> <li>3.执行派生类的构造函数体</li></ul></li></ul> <h3 id="_2-1-是先构造父类的虚表指针还是先构造父类的成员？"><a href="#_2-1-是先构造父类的虚表指针还是先构造父类的成员？" class="header-anchor">#</a> 2.1.是先构造父类的虚表指针还是先构造父类的成员？</h3> <ul><li>虚表指针</li></ul> <h3 id="_2-2-虚表指针和构造函数体那个先被构造？"><a href="#_2-2-虚表指针和构造函数体那个先被构造？" class="header-anchor">#</a> 2.2.虚表指针和构造函数体那个先被构造？</h3> <ul><li>虚表指针先构造</li></ul> <h3 id="_3-c-运行构造函数的时候虚函数表被构造出来了么？"><a href="#_3-c-运行构造函数的时候虚函数表被构造出来了么？" class="header-anchor">#</a> 3.c++运行构造函数的时候虚函数表被构造出来了么？</h3> <ul><li>构造出来了。因为虚函数表是在<strong>编译时</strong>由编译器创建，在<strong>运行</strong>时肯定已经创建完成。</li></ul> <h3 id="_4-析构一个派生类对象的过程："><a href="#_4-析构一个派生类对象的过程：" class="header-anchor">#</a> 4.析构一个派生类对象的过程：</h3> <ul><li><p>1.<strong>递归</strong>析构派生类部分：</p> <ul><li>1.将实例的虚表指针指向<strong>派生类vtbl</strong></li> <li>2.执行派生类的<strong>析构函数体</strong></li> <li>3.析构派生类的<strong>成员变量</strong></li></ul></li> <li><p>2.析构基类部分：</p> <ul><li>1.将实例的虚表指针指向基类的vtbl</li> <li>2.执行基类的析构函数函数体</li> <li>3.析构基类的成员变量</li></ul></li></ul> <h2 id="✅基础"><a href="#✅基础" class="header-anchor">#</a> ✅基础</h2> <h3 id="_1-vector是线程安全的吗？"><a href="#_1-vector是线程安全的吗？" class="header-anchor">#</a> 1.vector是线程安全的吗？</h3> <ul><li>不是线程安全的！</li> <li>参考：《Linux多线程服务器端编程》P4</li> <li>巨人网络</li></ul> <h3 id="_2-c-是不是类型安全的呢？"><a href="#_2-c-是不是类型安全的呢？" class="header-anchor">#</a> 2.C++是不是类型安全的呢？</h3> <ul><li>C++<strong>不是</strong>类型安全的</li> <li>在C++中允许不同类型指针之间进行强制转换（<code>C#</code>是类型安全的）</li></ul> <h3 id="_3-sizeof只有1个虚析构函数的空类呢？"><a href="#_3-sizeof只有1个虚析构函数的空类呢？" class="header-anchor">#</a> 3.sizeof只有1个虚析构函数的空类呢？</h3> <ul><li>64位的机器的话，那么就是8Byte，虚函数指针</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">sss</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
	<span class="token function">sss</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">sss</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	
	cout<span class="token operator">&lt;&lt;</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span> sss <span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
	<span class="token function">system</span><span class="token punctuation">(</span><span class="token string">&quot;pause&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><h3 id="_4-构造函数为什么不能是虚函数？"><a href="#_4-构造函数为什么不能是虚函数？" class="header-anchor">#</a> 4.构造函数为什么不能是虚函数？</h3> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">sss</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
	<span class="token keyword">virtual</span> <span class="token function">sss</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	 <span class="token operator">~</span><span class="token function">sss</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	sss a<span class="token punctuation">;</span>
	cout<span class="token operator">&lt;&lt;</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span> sss <span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
	<span class="token function">system</span><span class="token punctuation">(</span><span class="token string">&quot;pause&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><ul><li>64位机器，64位<code>g++</code> <ul><li>运行报错：<code>error: constructors cannot be declared virtual [-fpermissive]</code></li></ul></li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>constructors cannot be declared virtual [-fpermissive]
构造函数不能声明为virtual [-fpermissive]
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><ul><li>参考：『Bjarne Stroustrup's C++ Style and Technique FAQ』</li> <li>参考：<a href="https://www.stroustrup.com/index.html" target="_blank" rel="noopener noreferrer">https://www.stroustrup.com/index.html<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>Why don<span class="token number">'</span>t we have <span class="token keyword">virtual</span> constructors<span class="token operator">?</span>
A <span class="token keyword">virtual</span> call is a mechanism to get work done given partial information<span class="token punctuation">.</span> In particular<span class="token punctuation">,</span> <span class="token string">&quot;virtual&quot;</span> allows us to call a function knowing only an interfaces <span class="token operator">and</span> <span class="token operator">not</span> the exact type of the object<span class="token punctuation">.</span> To create an object you need complete information<span class="token punctuation">.</span> In particular<span class="token punctuation">,</span> you need to know the exact type of what you want to create<span class="token punctuation">.</span> Consequently<span class="token punctuation">,</span> a <span class="token string">&quot;call to a constructor&quot;</span> cannot be <span class="token keyword">virtual</span><span class="token punctuation">.</span>


为什么我们没有虚拟构造函数？
虚拟调用是在给定部分信息的情况下完成工作的机制。特别是，“虚拟”允许我们调用一个只知道接口而不知道对象确切类型的函数。
    要创建对象，您需要完整的信息。特别是，您需要知道您想要创建的内容的确切类型。因此，“对构造函数的调用”不能是虚拟的。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h3 id="_5-为何空类的大小不是零？"><a href="#_5-为何空类的大小不是零？" class="header-anchor">#</a> 5.为何空类的大小不是零？</h3> <ul><li>为了<strong>确保两个不同对象的地址不同</strong>，必须如此</li> <li>也正因为如此，new返回的指针总是指向不同的单个对象。我们还是来看代码吧：</li> <li>参考文献<a href="https://www.stroustrup.com/bstechfaq.htm" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">Empty</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    Empty a<span class="token punctuation">,</span> b<span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token operator">&amp;</span>a<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span> <span class="token punctuation">)</span> 
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;impossible: report error to compiler supplier\n&quot;</span><span class="token punctuation">;</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;不可能:向编译器供应商报告错误\n&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    Empty<span class="token operator">*</span> p1 <span class="token operator">=</span> <span class="token keyword">new</span> Empty<span class="token punctuation">;</span>
    Empty<span class="token operator">*</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> Empty<span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>p1 <span class="token operator">==</span> p2<span class="token punctuation">)</span> 
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;impossible: report error to compiler supplier\n&quot;</span><span class="token punctuation">;</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;不可能:向编译器供应商报告错误\n&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>	
<span class="token comment">//我在64位机器，64位g++上，运行了，发现什么都没输出</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><ul><li>另外，C++中有一条有趣的规则——空基类并不需要另外一个字节来表示：</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">struct</span> <span class="token class-name">X</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token class-name">Empty</span></span> <span class="token punctuation">{</span>
		<span class="token keyword">int</span> a<span class="token punctuation">;</span>
		<span class="token comment">// ...</span>
	<span class="token punctuation">}</span><span class="token punctuation">;</span>

	<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span>X<span class="token operator">*</span> p<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token keyword">void</span><span class="token operator">*</span> p1 <span class="token operator">=</span> p<span class="token punctuation">;</span>
		<span class="token keyword">void</span><span class="token operator">*</span> p2 <span class="token operator">=</span> <span class="token operator">&amp;</span>p<span class="token operator">-&gt;</span>a<span class="token punctuation">;</span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span>p1 <span class="token operator">==</span> p2<span class="token punctuation">)</span> 
        <span class="token punctuation">{</span>
            cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;nice: good optimizer&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
            cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;nice：很好的优化器&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
	<span class="token punctuation">}</span>
<span class="token comment">//我在64位机器，64位g++上，运行了，输出了上面的</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><ul><li>如果上述代码中p1和p2相等，那么<strong>说明编译器作了优化</strong>。</li> <li>这样的优化是安全的，而且非常有用。它允许程序员用空类来表示非常简单的概念，而不需为此付出额外的（空间）代价。一些现代编译器提供了这种“虚基类优化”功能。</li></ul> <h3 id="_6-我能从构造函数调用虚函数吗？"><a href="#_6-我能从构造函数调用虚函数吗？" class="header-anchor">#</a> 6.我能从构造函数调用虚函数吗？</h3> <ul><li><p><strong>可以。不过你得悠着点</strong>。</p></li> <li><p>当你这样做时，也许你自己都不知道自己在干什么！在构造函数中，虚拟机制尚未发生作用，因为此时overriding尚未发生。万丈高楼平地起，总得先打地基吧？对象的建立也是这样——先把基类构造完毕，然后在此基础上构造派生类。</p></li> <li><p>参考自<a href="https://www.stroustrup.com/bstechfaq.htm" target="_blank" rel="noopener noreferrer">文章<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li></ul> <h3 id="_7-内存泄露及解决办法："><a href="#_7-内存泄露及解决办法：" class="header-anchor">#</a> 7.内存泄露及解决办法：</h3> <ul><li>什么是内存泄露？</li></ul> <p>简单地说就是申请了一块内存空间，<strong>使用完毕后没有释放掉</strong></p> <ul><li>（1）new和malloc申请资源使用 后，没有用delete和free释放；</li> <li>（2）子类继承父类时，父类析构函数不是虚函数。</li> <li>（3） Windows句柄资源使用后没有释放。</li></ul> <h3 id="_8-怎么检测内存泄漏？"><a href="#_8-怎么检测内存泄漏？" class="header-anchor">#</a> 8.怎么检测内存泄漏？</h3> <ul><li>第一：良好的编码习惯，使用了内存分配的函数，一旦使用完毕,要记得使用其相应的函数释放掉。</li> <li>第二：将分配的内存的指针以链表的形式自行管理，使用完毕之后从链表中删除，程序结束时可检查改链表。</li> <li>第三：使用智能指针。</li> <li>第四：一些常见的工具插件，如ccmalloc、Dmalloc、Leaky、==Valgrind==等等。</li></ul> <h2 id="✅平常做题错题"><a href="#✅平常做题错题" class="header-anchor">#</a> ✅平常做题错题</h2> <h3 id="_1-测试"><a href="#_1-测试" class="header-anchor">#</a> 1.测试</h3> <ul><li>题目参考<a href="https://www.nowcoder.com/test/question/done?tid=44295104&qid=112041" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>


<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span> 
	<span class="token keyword">char</span> s<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">&quot;123&quot;</span><span class="token punctuation">,</span><span class="token operator">*</span>p<span class="token punctuation">;</span>
	p<span class="token operator">=</span>s<span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%c%c%c\n&quot;</span><span class="token punctuation">,</span><span class="token operator">*</span>p<span class="token operator">++</span><span class="token punctuation">,</span><span class="token operator">*</span>p<span class="token operator">++</span><span class="token punctuation">,</span><span class="token operator">*</span>p<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">system</span><span class="token punctuation">(</span><span class="token string">&quot;pause&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//以下程序的输出结果是（）。</span>
<span class="token comment">//321</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>牛油的回答</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>2. 运算对象求值顺序不明：
C++中只有'&amp;&amp;', '||', ',', '?:' 这四个运算符明确了其所属运算对象的求值顺序。

函数调用也是一种运算符
而实参压栈顺序完全依赖于编译器实现，三个*p++求值顺序不明。
那么结合第一个问题，假如从左向右压栈结果就是123
如果换个编译器可能顺序又不同了
所有选项可能都能有幸成为正确答案

所以，这种表达式是错误的，会产生未定义的行为。
这种题目真的不该再出。


大家看的所谓语言书籍的作者当年基本都是i386的使用者
这就是大家看到“压栈顺序从右至左”这一说法的原因
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><ul><li>我的测试环境64位机器的<code>g++</code>下</li> <li>实参压栈顺序是『从右到左』</li></ul> <h3 id="_02-在-c-语言中，对函数参数默认值描述正确的是？"><a href="#_02-在-c-语言中，对函数参数默认值描述正确的是？" class="header-anchor">#</a> 02.在 c++ 语言中，对函数参数默认值描述正确的是？</h3> <ul><li>题目<a href="https://www.nowcoder.com/test/question/done?tid=44202421&qid=143523#summary" target="_blank" rel="noopener noreferrer">来源<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>A 函数参数的默认值只能设定一个
B 一个函数的参数若有多个，则参数默认值的设定可以不连续
C 函数参数必须设定默认值
D 在设定了参数的默认值后，该参数后面定义的所有参数都必须设定默认值
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><ul><li>我选择的是D</li> <li>2020-10-02
<ul><li>我当时的解释：C++语言中，允许在函数的说明或定义时给一个或多个参数指定默认值。<strong>参数默认值必须从右向左定义</strong>（入栈的顺序，汇编），即在一个指定了默认值的参数的右边，不能出现没有指定默认值的参数。</li></ul></li> <li>2021.7月
<ul><li>我对上面的解释：关于汇编的那个事情，我突然记得那时候我学的是X86的汇编</li></ul></li></ul> <h2 id="✅c-输入输出io"><a href="#✅c-输入输出io" class="header-anchor">#</a> ✅C++输入输出IO</h2> <h2 id="_01-iostream的设计初衷"><a href="#_01-iostream的设计初衷" class="header-anchor">#</a> 01.<code>iostream</code>的设计初衷</h2> <ul><li>对初学者友好</li> <li>提供一个高效的可扩展的类型安全的IO机制</li></ul> <blockquote><p><code>iostream</code>的现状</p></blockquote> <ul><li>在真实的项目中很少用到<code>iostream</code> <ul><li>参考自“陈硕”</li></ul></li></ul> <h2 id="_02-iostream的特点"><a href="#_02-iostream的特点" class="header-anchor">#</a> 02.<code>iostream</code>的特点</h2> <ul><li>不同于标准库其他class的“值语义(value semantics)”，<code>iostream</code>是“对象语义(object semantics)”
<ul><li>即iostream是<code>non-copyable</code></li> <li>iostream禁止拷贝，利用对象的生命期来明确管理资源（如文件）</li></ul></li> <li><code>iostream</code>在<strong>线程安全</strong>方面没有保证！</li></ul> <h2 id="✅c-高阶论题"><a href="#✅c-高阶论题" class="header-anchor">#</a> ✅C++高阶论题</h2> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>术语
	内存泄漏
c++编程风格惯用法
	1.类初始化列表
	2.枚举类替换命名空间
	3.RAII(资源获取即初始化)
	4.copy and swap
	5.pImpl(指针指向具体实现)
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="_01-c-惯用法"><a href="#_01-c-惯用法" class="header-anchor">#</a> 01.C++惯用法</h2> <h3 id="_1-1-raii-资源获取即初始化"><a href="#_1-1-raii-资源获取即初始化" class="header-anchor">#</a> 1.1.RAII(资源获取即初始化)</h3> <blockquote><p>RAII（资源获取即初始化）『<strong>R</strong>esource <strong>A</strong>cquisition <strong>I</strong>s <strong>I</strong>nitialization』</p></blockquote> <ul><li><a href="https://zh.wikipedia.org/wiki/RAII" target="_blank" rel="noopener noreferrer">维基百科<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>：RAII</li> <li>为解决资源管理时的<font style="background:yellow;">异常安全性</font></li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>它是在一些面向对象语言中的一种惯用法。

RAII源于C++
在Java，C#，D，Ada，Vala和Rust中也有应用
1984-1989年期间，比雅尼·斯特劳斯特鲁普和安德鲁·柯尼希在设计C++异常时，为解决资源管理时的异常安全性而使用了该用法[1]，后来比雅尼·斯特劳斯特鲁普将其称为RAII[2]。

RAII要求，资源的有效期与持有资源的对象的生命期严格绑定，即由对象的构造函数完成资源的分配（获取），同时由析构函数完成资源的释放。在这种要求下，只要对象能正确地析构，就不会出现资源泄露问题。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h3 id="_1-2-pimpl"><a href="#_1-2-pimpl" class="header-anchor">#</a> 1.2.pImpl</h3> <blockquote><p>pImpl（指向实现的指针）『<strong>P</strong>ointer to <strong>Impl</strong>ementation』，Implementation，实现，实施</p></blockquote> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>是一种 C++ 编程技巧
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><ul><li>它将类的<strong>实现细节</strong>从对象表示中移除，放到一个『<strong>分离的类</strong>』中，并以一个『<strong>不透明的指针</strong>』进行访问。</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>优点：
	1、减少依赖项（降低耦合性）：其一减少原类不必要的头文件的依赖，加速编译；其二对Impl类进行修改，无需重新编译原类。
	2、接口和实现的分离（隐藏了类的实现）：私有成员完全可以隐藏在共有接口之外，给用户一个间接明了的使用接口，尤其适合闭源API设计。
	3、可使用惰性分配技术：类的某部分实现可以写成按需分配或者实际使用时再分配，从而节省资源。
	
缺点：
	1、每个类需要占用小小额外的指针内存。
	
	2、每个类每次访问具体实现时都要多一个间接指针操作的开销，并且在使用、阅读和调试上都可能有所不便
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><ul><li>参考自：<a href="https://www.cnblogs.com/KillerAery/p/9539705.html" target="_blank" rel="noopener noreferrer">博客园<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <h3 id="_1-3-copy-and-swap"><a href="#_1-3-copy-and-swap" class="header-anchor">#</a> 1.3.copy and swap</h3> <h2 id="_02-value-semantics和object-semantics"><a href="#_02-value-semantics和object-semantics" class="header-anchor">#</a> 02.<code>value semantics</code>和<code>object semantics</code></h2> <ul><li>参考自：《Linux多线程服务器编程》，使用muduoC++网络库</li></ul> <p><font style="background:yellow;">仔细理解：书上P482-484</font></p> <h3 id="_2-1-值语义（value-semantics）"><a href="#_2-1-值语义（value-semantics）" class="header-anchor">#</a> 2.1.值语义（value semantics）</h3> <ul><li>所谓值语义是指目标对象由源对象拷贝生成，且生成后与源对象完全无关，彼此独立存在，改变互不影响。就像 int 类型变量相互拷贝一样。</li> <li>value semantics：指的是对象的拷贝与原对象无关</li></ul> <blockquote><p>举例：</p></blockquote> <ul><li><font style="background:yellow;">C++</font>的内置类型（<code>bool/int/double/char</code>）都是值语义，标准库里的 <code>complex&lt;&gt;</code>、<code>pair&lt;&gt;</code>、<code>vector&lt;&gt;</code>、<code>map&lt;&gt;</code>、<code>string</code> 等等类型也都是值语义。</li> <li><font style="background:yellow;">Java</font>语言中的<code>primitive types（基础类型）比如：int 、short、long</code>也是值语义</li></ul> <p><strong>拷贝之后就与源对象完全脱离关系</strong></p> <h3 id="_2-2-对象语义（object-semantics）"><a href="#_2-2-对象语义（object-semantics）" class="header-anchor">#</a> 2.2.对象语义（object semantics）</h3> <ul><li><font style="background:yellow;">别名：</font>对象语义也叫<strong>指针语义</strong>，**引用语义（reference semantics）**等</li> <li>通常是指一个目标对象由源对象拷贝生成，但生成后与源对象之间依然共享底层资源，对任何一个的改变都将随之改变另一个。就像包含有指针成员变量的自定义类在默认拷贝构造函数下对其对象之间进行的拷贝。拷贝后目标对象和源对象的指针成员变量仍指向同一块内存数据。如果当其中一个被析构掉后，另一个对象的指针成员就会沦为名副其实的悬垂指针！</li></ul> <p>核心理解：”对象语义“这个词中“对象”指的是<font style="background:yellow;">『<strong>面向对象</strong>』</font>意义下的对象，并不是我们<font style="background:yellow;">『<strong>语法意义上class生成的</strong>』</font>对象，我们的结论是：『面向对象意义下的对象，对象拷贝是禁止的』</p> <ul><li>例子：</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>薪资管理系统中，一个对象叫：员工张三
我们拷贝“员工张三”这个对象是没有意义的！！
因为员工张三这个对象代表的是一个活生生的人，我们拷贝它是被禁止的。

服务器开发中，也有类似的情况
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><ul><li>结论：<font style="background:yellow;">『面向对象』意义下的&quot;对象&quot;是<code>non-copyable</code>（不能够拷贝的）</font></li></ul> <blockquote><p>举例：</p></blockquote> <ul><li><p><font style="background:yellow;">Java</font>语言中class对象<font style="background:yellow;">都是</font>“对象语义”</p> <ul><li><font style="background:yellow;">Java</font>语言没有办法实现『真正的』“值语义”class，只好用<code>immutable object</code>来模拟</li> <li><font style="background:yellow;">Java</font>语言中有<code>value object</code>一说，按照定义，它实际上是<code>immutable object（不可改变的对象）</code>，比如<code>Interger，String，BigInterger</code></li></ul></li> <li><p><font style="background:yellow;">C++</font>语言中class本质上是<font style="background:yellow;">值语义</font>，值语义对象，比如<code>pair&lt;&gt;，vector&lt;&gt;，string&lt;&gt;</code>等，都是可修改的（mutable）</p></li></ul> <h3 id="_2-3-优点缺点对比"><a href="#_2-3-优点缺点对比" class="header-anchor">#</a> 2.3.优点缺点对比</h3> <p>值语义（value semantics）</p> <ul><li>优点：生命期管理很简单，比如 C++中<code>int</code>类型一样—你不需要操心 int 对象 的生命期。
<ul><li>因为：值语义的对象要么是<code>stack object</code>，要么是<code>作为其他object的成员</code></li></ul></li></ul> <p>对象语义（object semantics）</p> <ul><li><p>缺点：对象语义的object由于不能拷贝，因此我们只能在<font style="background:yellow;">C++的实现</font>是通过’指针“或”引用“来使用它</p></li> <li><p><code>immutable</code>不可修改的</p></li> <li><p><code>mutable</code>可修改的</p></li></ul> <h2 id="_03-c-惯用法和value-semantics组合拳"><a href="#_03-c-惯用法和value-semantics组合拳" class="header-anchor">#</a> 03.C++惯用法和<code>value semantics</code>组合拳</h2> <ul><li>值语义，对象语义</li> <li>RAII</li> <li>智能指针</li></ul> <h3 id="_3-1-c-的值语义是『双刃剑』"><a href="#_3-1-c-的值语义是『双刃剑』" class="header-anchor">#</a> 3.1.C++的值语义是『双刃剑』</h3> <ul><li>由于C++中class本质上是<font style="background:yellow;">值语义</font>，这
<ul><li>才会出现<code>object slicing</code>这种语言独有的问题！！</li> <li>才会需要程序员注意：<code>pass-by-value</code>和<code>pass-by-const-reference</code>的取舍</li></ul></li> <li>在其他『面向对象语言』，比如Java中，这都不需要费脑筋。。</li></ul> <p>书上P488</p> <ul><li>值语义是<strong>C++语言3大约束之一</strong>，C++的设计初衷是让用户定义的类型（class）能像内置类型（int）一样工作，具有<strong>同等</strong>的地位。</li></ul> <h3 id="_3-3-问题：智能指针？"><a href="#_3-3-问题：智能指针？" class="header-anchor">#</a> 3.3.问题：智能指针？</h3> <ul><li><font style="background:yellow;">智能指针既不是『值语义』也不是『对象语义』</font></li> <li>由于『值语义和对象语义的原因』
<ul><li><font style="background:yellow;">如果不使用智能指针，用C++做面向对象编程将会困难重重</font></li></ul></li></ul> <h2 id="_04-c-语言层面高度探讨"><a href="#_04-c-语言层面高度探讨" class="header-anchor">#</a> 04.C++语言层面高度探讨</h2> <p>C++复杂的根源在于三大约束：</p> <ul><li>与C的完全兼容</li> <li>静态类型检查</li> <li>最高性能</li></ul> <p><strong>在三大约束下，C++未能完善对于面向对象思想的支持，未能建立强大的动态能力，从而使得C++在OO这个单项上存在本质缺陷</strong>。</p> <ul><li>事实上，C++的过程、OB模型相当成熟和稳定</li> <li>而泛型模型，就单项来说，除了语法丑陋之外也没有大的问题。</li> <li>缺陷集中体现在OO模型的实现，并因此干扰了其他几个范式的完整程度。
<ul><li>然而，OO的缺陷绝非设计者的偏执，其原因在于三大约束。如果坚持三大约束，则即使再重新设计一次，结果也与今日相差不远。Stroustrup在多种场合表示，对C++的设计没有大的后悔之处，意思就是这个。</li> <li>侯捷先生早在2001年初即对我说，C++在OO上不及Java，当时体会不深，认为没有大一统的单根类库会使设计更加灵活，后来又认为凭借GP可以抵消OO的不足甚至超越之，现在看来即使不是不可能，这条道路也必然是艰辛异常，成败难以预料。</li></ul></li></ul> <blockquote><p>参考自：<a href="https://blog.csdn.net/myan/article/details/148900" target="_blank" rel="noopener noreferrer">CSDN的myan（孟岩）<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h2 id="_05-c-的编程范式"><a href="#_05-c-的编程范式" class="header-anchor">#</a> 05.C++的编程范式</h2> <h3 id="_5-1-过程式编程"><a href="#_5-1-过程式编程" class="header-anchor">#</a> 5.1.过程式编程</h3> <h3 id="_5-2-基于对象编程"><a href="#_5-2-基于对象编程" class="header-anchor">#</a> 5.2.基于对象编程</h3> <h3 id="_5-3-面向对象编程"><a href="#_5-3-面向对象编程" class="header-anchor">#</a> 5.3.面向对象编程</h3> <h3 id="_5-4-泛型编程"><a href="#_5-4-泛型编程" class="header-anchor">#</a> 5.4.泛型编程</h3> <h3 id="_5-5-函数式编程"><a href="#_5-5-函数式编程" class="header-anchor">#</a> 5.5.函数式编程</h3> <h2 id="🔋-参考资料"><a href="#🔋-参考资料" class="header-anchor">#</a> 🔋 参考资料</h2> <ul><li><p>孟岩<a href="https://blog.csdn.net/myan" target="_blank" rel="noopener noreferrer">在CSDN上的博客<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li> <li><p>《Linux多线程服务端编程》，陈硕</p></li> <li><p>光城，<a href="https://light-city.club/sc/" target="_blank" rel="noopener noreferrer">C++那些事<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li> <li><p>重要网站：『<a href="https://www.stroustrup.com/bs_faq2.html#virtual-ctor" target="_blank" rel="noopener noreferrer">Bjarne Stroustrup's C++ Style and Technique FAQ<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>』</p> <ul><li><a href="https://www.stroustrup.com/bs_faq2.html#virtual-ctor" target="_blank" rel="noopener noreferrer">https://www.stroustrup.com/bs_faq2.html#virtual-ctor<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></li> <li><p>当一个程序员足够老，他就从工程师变成了历史学家</p></li></ul></div> <div class="page-edit"><!----> <!----></div> <!----> </div> <!----></div></div>
    <script src="/assets/js/app.c70e21ad.js" defer></script><script src="/assets/js/25.14067b60.js" defer></script>
  </body>
</html>
